home *** CD-ROM | disk | FTP | other *** search
- **
- ** $Id: SearchRefs.asm,v 30.0 1994/06/10 18:05:50 dice Exp $
- **
- ** Search loaded reference file for reference. Search is "best match"
- ** for case: an exact match will return instantly. An inexact match
- ** will scan to the end looking for a better option.
- **
- ** :TODO: Investigate full international case sensitivity issues.
- ** We already do 90%.
- **
- ** Disallow tabs in search string
- **
- ** Could do "fast path" search of first char. 25 in 26 would
- ** hit it. Or maybe a BCPL-ish string length.
- **
- ** (C) Copyright 1992, Obvious Implementations, All Rights Reserved
- **
-
- XDEF _searchMe
- XDEF _convertFile
- XDEF _nextLine
-
- LF EQU 10
- TAB EQU 9
- FF EQU 12
-
- SKIPNL MACRO \1
- LP\@ tst.b (\1)+
- bne.s LP\@
- ENDM
-
- section text,code
-
- ;
- ; FUNCTION
- ; Return a newline separated file, line-by-line.
- ;
- ; INPUTS
- ; 4(SP) -Pointer to current index
- ;
- ; RESULTS
- ; D0 -Length of current line. Zero for end
- ;
- _nextLine: moveq #FF+1,d1 ;Pass anything numerically above FF without comment
- move.l 4(sp),a0
- move.l a0,a1
-
- nl_loop: cmp.b (a1)+,d1
- bcs.s nl_loop
- move.b -1(a1),d0
- beq.s nl_end
- cmp.b #FF,d0
- bne.s nl_noff
- move.b #LF,-1(a1) ;Replace FF with LF
- nl_noff: cmp.b #LF,d0
- bne.s nl_loop
-
- suba.l a0,a1
- move.l a1,d0
- rts ;exit _nextLine
-
- nl_end: subq.l #1,a1 ;Don't write NULL
- suba.l a0,a1
- move.l a1,d0
- rts ;exit _nextLine
-
- ;
- ; INPUTS
- ; 4(SP) File pointer
- ; 8(SP) Length. Will stick two NULLs *after* the end
- ;
- _convertFile: move.l 4(sp),a0
- move.l 8(sp),d0
- moveq #LF,d1 ;Convert newlines to nulls
-
- cf_lp: cmp.b (a0)+,d1
- bne.s cf_nolf
- clr.b -1(a0)
- cf_nolf: subq.l #1,d0
- bne.s cf_lp
-
- clr.b (a0)+
- clr.b (a0)+
- rts
-
-
- ;
- ; INPUTS
- ; D0 - Length of string array. Last entry *must* be LF terminated.
- ; A0 - Pointer to array of strings
- ; A1 - Search string
- ; A2 - Address of pointer to current filename string, filled in.
- ;
- ; RESULTS
- ; D0 - Pointer to proper string
- ; &A2 - Last matched filename
- ;
- ; REGISTERS
- ; &A2 - Last matched filename
- ; A3 - Current index
- ; A5 - Search string
- ; D2 - scratch
- ; D3 - <tab>
- ; D4 - Last matched name pointer
- ; D5 - Last matched Inacuracy index
- ; D6 - Current filename
- ; D7 - #$20 for case-match
- ;
- ;
- ; char * searchMe(char *strings,char *searchfor,&filename,ULONG length);
- STACKOFFSET EQU 11*4
- _searchMe: movem.l d2-d7/a2-a6,-(sp)
-
- ;---------------Register setup
- moveq #TAB,D3 ;<tab> for quick searches
- moveq #0,d4 ;Matched entry
- moveq #-1,d5 ;Infinite inaccuary index
- moveq #0,d6 ;In case no filenames found...
- moveq #~($20),d7 ;Setup for case search
-
- move.l STACKOFFSET+4(sp),a3 ;Main index
- move.l STACKOFFSET+8(sp),a5 ;Search string
- move.l STACKOFFSET+12(sp),a2 ;&filename pointer
- clr.l (a2) ;No filenmae yet
-
- move.l a5,d0 ;Test for NULL search string
- beq sm_alldone
-
- ;---------------Main loop
- bra.s sm_skipSKIPNL
- sm_newname: move.l a3,d6 ;Set new name pointer
- sm_toploop: SKIPNL a3
- sm_skipSKIPNL: move.b (a3),d2
- beq.s sm_alldone ;Double NULL indicates end...
- cmp.b #'~',d2 ;Check for ~ prefex
- beq.s sm_newname
-
- ; Compare current string, case insensitive. Each character
- ; of a case-insensitive match adds 1 to the inaccuracy index.
- ; A zero index ends the search, else the best is used.
- ;
- ; A simple folding search is used; while this results in
- ; some false matches, such a y-umlaut to sharffe-S, we don't
- ; really care. Any match is better than no match, and the
- ; inaccuracy index will weed out the better choice anyway.
- ;
- sm_notaname: move.l a5,a0 ;Search string
- move.l a3,a1 ;Stash current index, in case of match
- moveq #0,d1 ;Zero inaccuary index
-
- sm_nextchar: move.b (a0)+,d0
- beq.s sm_endsource ;End of search string...
- move.b (a3)+,d2
- cmp.b d3,d2
- beq.s sm_endcandid ;End of candidate string....
- cmp.b d2,d0
- beq.s sm_nextchar ;Match!
- addq.w #1,d1 ;Increase inaccuracy
- and.b d7,d0 ;Simple folding search
- and.b d7,d2 ;Simple folding search
- cmp.b d2,d0
- beq.s sm_nextchar ;Match!
- bra.s sm_toploop ;We struck out...
-
- ; Source string has ended. Count inaccuacy of 2 for each
- ; remaining character in the candidate string.
- ;
- sm_endsource: cmp.b (a3)+,d3
- beq.s sm_endmatch
- addq.w #2,d1 ;Increase inaccuracy
- bra.s sm_endsource
-
- ; Candidate string has ended. Count inaccuacy of 2 for each
- ; remaining character in the source string.
- ;
- sm_endcandid: addq.w #2,d1 ;Increase inaccuracy
- tst.b (a0)+
- bne.s sm_endcandid
-
- ; We have a match. Update pointers if better than our last
- ; match.
- ;
- sm_endmatch: cmp.l d5,d1 ;Current inaccuary index to old
- bcc.s sm_toploop ;Keep searching for perfection...
- move.l d6,(a2) ;Got one! Stash filename.
- move.l a1,d4 ;Got one! Stash pointer.
- move.l d1,d5 ;Got one! Stash inaccuracy index.
- bne.s sm_toploop ;Keep searching for perfection...
-
-
- ; All done. At this point we have nothing, a perfect match
- ; or a partial match. Tell the world.
- ;
- sm_alldone: move.l d4,d0 ;Return what we found
- ;[&A2 - pointer to current filename]
-
- movem.l (sp)+,d2-d7/a2-a6
- rts
- end
-